<template>
    <el-popover v-if="!hide" placement="bottom-end" :width="200" trigger="click">
        <div class="setting-body">
            <div class="action-line">
                <el-link type="primary" @click="resetFixed()">重置</el-link>
            </div>
            <el-checkbox-group v-model="selectCols" @change="selectChange">
                <div class="header" v-if="leftCols.length">
                    <div class="set-title">固定左侧</div>
                    <!-- <el-checkbox-group v-model="selectLeftCols" @change="selectChange"> -->
                    <div id="header-cols" ref="headerColsRef" class="cols">
                        <div class="col" v-for="col in leftCols" :class="col.prop" :key="col.prop">
                            <icon-svg name="drag" class="drag-icon"></icon-svg>
                            <el-checkbox :label="col.prop" :title="col.label">{{ col.label || col.prop
                            }}</el-checkbox>
                            <div class="action">
                                <el-tooltip content="取消固定">
                                    <icon-svg name="reset-fixed" class="fs-16 pointer ml-10"
                                        @click="toFixed(col.prop, false)"></icon-svg>
                                </el-tooltip>
                                <el-tooltip content="固定在列尾">
                                    <icon-svg name="top" class="fs-16 pointer rotate-180 ml-4"
                                        @click="toFixed(col.prop, 'right')"></icon-svg>
                                </el-tooltip>
                            </div>

                        </div>
                    </div>
                    <!-- </el-checkbox-group> -->
                </div>
                <div class="body">
                    <div class="set-title" v-if="leftCols.length || rightCols.length">不固定</div>
                    <!-- <el-checkbox-group v-model="selectAutoCols" @change="selectChange"> -->
                    <div id="body-cols" ref="colsRef" class="cols">
                        <div class="col" v-for="col in autoCols" :class="col.prop" :key="col.prop">
                            <icon-svg name="drag" class="drag-icon"></icon-svg>
                            <el-checkbox :label="col.prop" :title="col.label">{{ col.label || col.prop
                            }}</el-checkbox>
                            <div class="action">
                                <el-tooltip content="固定在列首">
                                    <icon-svg name="top" class="fs-16 pointer ml-10"
                                        @click="toFixed(col.prop, 'left')"></icon-svg>
                                </el-tooltip>
                                <el-tooltip content="固定在列尾">
                                    <icon-svg name="top" class="fs-16 pointer rotate-180 ml-4"
                                        @click="toFixed(col.prop, 'right')"></icon-svg>
                                </el-tooltip>
                            </div>

                        </div>
                    </div>
                    <!-- </el-checkbox-group> -->
                </div>
                <div class="bottom" v-if="rightCols.length">
                    <div class="set-title">固定右侧</div>
                    <!-- <el-checkbox-group v-model="selectRightCols" @change="selectChange"> -->
                    <div id="bottom-cols" ref="bottomColsRef" class="cols">
                        <div class="col" v-for="col in rightCols" :class="col.prop" :key="col.prop">
                            <icon-svg name="drag" class="drag-icon"></icon-svg>
                            <el-checkbox :label="col.prop" :title="col.label">{{ col.label || col.prop
                            }}</el-checkbox>
                            <div class="action">
                                <el-tooltip content="固定在列首">
                                    <icon-svg name="top" class="fs-16 pointer ml-10"
                                        @click="toFixed(col.prop, 'left')"></icon-svg>
                                </el-tooltip>
                                <el-tooltip content="取消固定">
                                    <icon-svg name="reset-fixed" class="fs-16 pointer rotate-180 ml-4"
                                        @click="toFixed(col.prop, false)"></icon-svg>
                                </el-tooltip>
                            </div>

                        </div>
                    </div>
                    <!-- </el-checkbox-group> -->
                </div>
            </el-checkbox-group>
        </div>
        <template #reference>
            <el-dropdown trigger="contextmenu" placement="bottom-end">
                <icon-svg name="setting" class="tb-setting"></icon-svg>
                <template #dropdown>
                    <el-dropdown-menu>
                        <el-dropdown-item @click="resetTable()">重置表格</el-dropdown-item>
                    </el-dropdown-menu>
                </template>
            </el-dropdown>
        </template>
    </el-popover>
</template>
<script lang="ts">
export default {
    name: 'TableConfig'
}
</script>
<script setup lang="ts">
import { ref, onMounted, computed, nextTick, Ref } from 'vue';
import _ from 'lodash'
import Sortable from 'sortablejs'
import CommonService from '@/service/common';
import { useRoute } from 'vue-router'

const commonService = new CommonService()
const route = useRoute()
const props = defineProps(['table', 'hide'])
const { table, hide } = props

const headerColsRef: Ref<Element | null> = ref(null)
const colsRef: Ref<Element | null> = ref(null)
const bottomColsRef: Ref<Element | null> = ref(null)

// 默认溢出显示...
table.columns = table.columns.map(col => {
    if (col.element) {
        const showTip = col.element.showOverflowTooltip
        col.element.showOverflowTooltip = typeof showTip !== 'undefined' ? showTip : true
    } else {
        col.element = {
            showOverflowTooltip: true
        }
    }
    return col
})

//本地代码的columns
const localFileColumns = _.cloneDeep(table.columns).map((res, index) => {
    res.sort = index
    return res
})

table.element = table.element || {
    border: true
}

if (table.index && table.indexConfig) {
    table.indexConfig.fixed = 'left'
}

const selectCols: any = ref([])

const orginCols: any = ref([])

let operateCols: any = table.columns
const setOrginCols = () => {
    orginCols.value = _.cloneDeep(operateCols).map((res, index) => {
        res.sort = index
        return res
    })
}

setOrginCols()
selectCols.value = orginCols.value.map(res => res.prop)

const selectChange = (val) => {
    table.columns = orginCols.value.filter(res => val.includes(res.prop))
    if (!val.length) {
        table.columns = [{ prop: '', label: '' }]
    }
    setTableCols()
}

const toFixed = (prop, type) => {
    const orginItem = operateCols.find(res => res.prop === prop)
    const item = table.columns.find(res => res.prop === prop)
    orginItem.element = orginItem.element || {}
    orginItem.element.fixed = type
    if (item) {
        item.element = item.element || {}
        item.element.fixed = type
    }

    setOrginCols()

    nextTick(() => {
        setTableCols()
        addSortable()
    })
}


const leftCols = computed(() => {
    return orginCols.value.filter(res => res.element?.fixed === 'left')
})

const rightCols = computed(() => {
    return orginCols.value.filter(res => res.element?.fixed === 'right')
})

const autoCols = computed(() => {
    return orginCols.value.filter(res => !res.element?.fixed)
})

const sortIds: string[] = []

const addSortable = () => {
    const headerCols = headerColsRef.value
    const cols = colsRef.value
    const bottomCols = bottomColsRef.value;
    [headerCols, cols, bottomCols].filter(el => !!el).forEach((el) => {
        if (el) {
            if (!sortIds.includes(el.id)) {
                new Sortable(el, {
                    draggable: ".col",
                    handle: '.drag-icon',
                    dragClass: "sortable-drag",
                    chosenClass: "sortable-chosen",
                    direction: 'vertical',
                    onEnd: (/**Event*/evt: { oldIndex: number, newIndex: number }) => {
                        const leftFixedItems = leftCols.value
                        const rightFixedItems = rightCols.value
                        const autoItems = autoCols.value
                        if (el.id === 'body-cols') {
                            const item = autoItems[evt.oldIndex]
                            if (evt.newIndex > evt.oldIndex) {
                                autoItems.splice(evt.newIndex + 1, 0, item)
                                autoItems.splice(evt.oldIndex, 1)
                            } else {
                                autoItems.splice(evt.newIndex, 0, item)
                                autoItems.splice(evt.oldIndex + 1, 1)
                            }
                        } else if (el.id === 'header-cols') {
                            const item = leftFixedItems[evt.oldIndex]
                            if (evt.newIndex > evt.oldIndex) {
                                leftFixedItems.splice(evt.newIndex + 1, 0, item)
                                leftFixedItems.splice(evt.oldIndex, 1)
                            } else {
                                leftFixedItems.splice(evt.newIndex, 0, item)
                                leftFixedItems.splice(evt.oldIndex + 1, 1)
                            }
                        } else if (el.id === 'bottom-cols') {
                            const item = rightFixedItems[evt.oldIndex]
                            if (evt.newIndex > evt.oldIndex) {
                                rightFixedItems.splice(evt.newIndex + 1, 0, item)
                                rightFixedItems.splice(evt.oldIndex, 1)
                            } else {
                                rightFixedItems.splice(evt.newIndex, 0, item)
                                rightFixedItems.splice(evt.oldIndex + 1, 1)
                            }
                        }

                        operateCols = [...leftFixedItems, ...autoItems, ...rightFixedItems]
                        table.columns = operateCols.filter(res => selectCols.value.includes(res.prop))
                        setOrginCols()

                        setTableCols()
                    },
                })
            }
            sortIds.push(el.id)
        }

    })
}

const setTableCols = () => {
    commonService.setTableCols({
        pageId: route.name,
        tableId: table.id,
        tableColumn: JSON.stringify(orginCols.value),
        visibleColumn: JSON.stringify(selectCols.value)
    })
}

const getTableCols = async () => {
    const data = await commonService.getTableCols({
        pageId: route.name,
        tableId: table.id,
    })
    if (data.data) {
        if (data.data.tableColumn) {
            operateCols = JSON.parse(data.data.tableColumn)
            const props = operateCols.map(res => res.prop)
            const padCols = localFileColumns.filter(res => !props.includes(res.prop))

            // 如果本地新增字段，则存入数据库
            if (padCols.length) {
                operateCols = [...operateCols, ...padCols]
                setOrginCols()
                setTableCols()
            } else {
                setOrginCols()
            }
            if (data.data.visibleColumn) {
                selectCols.value = JSON.parse(data.data.visibleColumn)
                if (padCols.length) {
                    const padProps = padCols.map(res => res.prop)
                    selectCols.value = [...selectCols.value, ...padProps]
                }
                table.columns = operateCols.filter(res => selectCols.value.includes(res.prop))
            }
        }
    }
}

const resetTable = async () => {
    table.loading = true
    const resetSelectCols = localFileColumns.map(res => res.prop)
    await commonService.setTableCols({
        pageId: route.name,
        tableId: table.id,
        tableColumn: JSON.stringify(localFileColumns),
        visibleColumn: JSON.stringify(resetSelectCols)
    })

    await getTableCols()

    table.loading = false
}

const resetFixed = () => {
    resetTable()
}

onMounted(() => {
    if (!hide) {
        addSortable()
    }
    getTableCols()
})


</script>
<style lang="scss" scoped>
.setting-body {
    max-height: 500px;
    overflow-y: auto;

    :deep(.el-checkbox) .el-checkbox__label {
        max-width: 80px;
        overflow: hidden;
        display: inline-block;
        text-overflow: ellipsis;
    }

    .action-line {
        display: flex;
        justify-content: flex-end;
        border-bottom: 1px solid #e5e5e5;
        padding-bottom: 5px;
    }
}

.tb-setting {
    font-size: 20px;
    cursor: pointer;
    color: #303133;

    &:focus {
        outline: none;
    }

}

.action {
    display: inline-flex;
    align-items: center;
    color: $primary--color;
    display: none;
}

.set-title {
    font-size: 12px;
    color: #ccc;
    height: 26px;
    display: flex;
    align-items: center;
}

.header,
.body,
.bottom {
    .col {
        display: flex;
        align-items: center;

        &:hover {
            .action {
                display: block;
            }
        }
    }
}

.drag-icon {
    font-size: 20px;
    margin-right: 10px;
    cursor: pointer;
}

.sortable-drag {
    background-color: #f5f5f5;
}

.sortable-chosen {
    background-color: #f5f5f5;
}
</style>